/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * MainGUI.java
 *
 * Created on Jan 1, 2012, 3:56:52 PM
 */
package com.darkprograms.speech.gui;

import com.darkprograms.speech.microphone.Microphone;
import com.darkprograms.speech.recognizer.GoogleResponse;
import com.darkprograms.speech.recognizer.Recognizer;
import com.darkprograms.speech.synthesiser.Synthesiser;
import com.darkprograms.speech.util.AePlayWave;
import com.freedomotic.googlespeech.GoogleSpeech;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.sound.sampled.AudioFileFormat;
import javazoom.jl.player.Player;

/**
 *
 * @author User
 */
public class MainGUI extends javax.swing.JFrame {

    GoogleSpeech plugin;
    File temp = null;

    /**
     * Creates new form MainGUI
     */
    public MainGUI(GoogleSpeech plugin) {
        this.plugin = plugin;
        initComponents();
        languageCode.setText(plugin.LANGUAGE_CODE);
        new Thread(new MicrophoneState()).start();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jSeparator1 = new javax.swing.JSeparator();
        jLabel4 = new javax.swing.JLabel();
        jSeparator2 = new javax.swing.JSeparator();
        jLabel5 = new javax.swing.JLabel();
        state = new javax.swing.JTextField();
        jLabel7 = new javax.swing.JLabel();
        status = new javax.swing.JTextField();
        jLabel8 = new javax.swing.JLabel();
        response = new javax.swing.JTextField();
        jLabel9 = new javax.swing.JLabel();
        confidence = new javax.swing.JTextField();
        jLabel10 = new javax.swing.JLabel();
        jLabel11 = new javax.swing.JLabel();
        synthStatus = new javax.swing.JTextField();
        jLabel12 = new javax.swing.JLabel();
        synthText = new javax.swing.JTextField();
        playSynth = new javax.swing.JButton();
        jLabel14 = new javax.swing.JLabel();
        languageCode = new javax.swing.JTextField();
        startRecognition = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Google Speech Plugin");

        jLabel4.setText("Microphone and Recognizer");

        jLabel5.setText("Microphone State:");

        state.setEditable(false);

        jLabel7.setText("Status:");

        status.setEditable(false);
        status.setText("Waiting...");

        jLabel8.setText("Response:");

        response.setEditable(false);

        jLabel9.setText("Confidence:");

        confidence.setEditable(false);

        jLabel10.setText("Synthetizer");

        jLabel11.setText("Status:");

        synthStatus.setEditable(false);
        synthStatus.setText("Waiting...");

        jLabel12.setText("Enter Text:");

        playSynth.setText("Say this");
        playSynth.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                playSynthActionPerformed(evt);
            }
        });

        jLabel14.setText("Enter Language Code:");

        languageCode.setText("en-US");

        startRecognition.setText("Start recognition");
        startRecognition.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                startRecognitionActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jLabel4)
                        .addGap(2, 2, 2)
                        .addComponent(jSeparator2))
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jLabel10)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jSeparator1))
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(jLabel12)
                                .addGap(3, 3, 3)
                                .addComponent(synthText, javax.swing.GroupLayout.PREFERRED_SIZE, 482, javax.swing.GroupLayout.PREFERRED_SIZE))
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(jLabel5)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(state, javax.swing.GroupLayout.PREFERRED_SIZE, 257, javax.swing.GroupLayout.PREFERRED_SIZE))
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(jLabel7)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(status, javax.swing.GroupLayout.PREFERRED_SIZE, 170, javax.swing.GroupLayout.PREFERRED_SIZE))
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(jLabel14)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(languageCode, javax.swing.GroupLayout.PREFERRED_SIZE, 114, javax.swing.GroupLayout.PREFERRED_SIZE))
                            .addComponent(startRecognition)
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(jLabel8)
                                .addGap(4, 4, 4)
                                .addComponent(response, javax.swing.GroupLayout.PREFERRED_SIZE, 229, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(jLabel9)
                                .addGap(3, 3, 3)
                                .addComponent(confidence, javax.swing.GroupLayout.PREFERRED_SIZE, 92, javax.swing.GroupLayout.PREFERRED_SIZE))
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(jLabel11)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(synthStatus, javax.swing.GroupLayout.PREFERRED_SIZE, 164, javax.swing.GroupLayout.PREFERRED_SIZE))
                            .addComponent(playSynth))
                        .addGap(0, 40, Short.MAX_VALUE)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(20, 20, 20)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jLabel4)
                    .addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(20, 20, 20)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel5)
                    .addComponent(state, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel14)
                    .addComponent(languageCode, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel7)
                    .addComponent(status, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(startRecognition)
                .addGap(18, 18, 18)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel8)
                    .addComponent(response, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel9)
                    .addComponent(confidence, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(40, 40, 40)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel10)
                    .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel11)
                    .addComponent(synthStatus, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(18, 18, 18)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel12)
                    .addComponent(synthText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(18, 18, 18)
                .addComponent(playSynth)
                .addContainerGap(26, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents
    protected Microphone microphone = new Microphone(AudioFileFormat.Type.WAVE);
    protected AePlayWave aePlayWave;

    private void playSynthActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_playSynthActionPerformed
        setSynthStatus("Playing...");

        new Thread(new PlayMP3Thread()).start();
    }//GEN-LAST:event_playSynthActionPerformed

    private void startRecognitionActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_startRecognitionActionPerformed
        try {
            temp = File.createTempFile("audio-file", ".tmp");
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        try {
            startRecognition.setEnabled(false);
            microphone.captureAudioToFile(temp);
            setStatus("Recording ...");
            
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        try {
             Thread.sleep(plugin.RECORD_TIME);
        } catch (InterruptedException ex) {
            Logger.getLogger(MainGUI.class.getName()).log(Level.SEVERE, null, ex);
            Thread.currentThread().interrupt();
        }
        microphone.close();
        new Thread(new RecognizeThread()).start();
        temp.deleteOnExit();

    }//GEN-LAST:event_startRecognitionActionPerformed

    private void setStatus(String status) {
        this.status.setText(status);
    }

    private void setSynthStatus(String status) {
        this.synthStatus.setText(status);
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JTextField confidence;
    private javax.swing.JLabel jLabel10;
    private javax.swing.JLabel jLabel11;
    private javax.swing.JLabel jLabel12;
    private javax.swing.JLabel jLabel14;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JLabel jLabel8;
    private javax.swing.JLabel jLabel9;
    private javax.swing.JSeparator jSeparator1;
    private javax.swing.JSeparator jSeparator2;
    private javax.swing.JTextField languageCode;
    private javax.swing.JButton playSynth;
    private javax.swing.JTextField response;
    private javax.swing.JButton startRecognition;
    private javax.swing.JTextField state;
    private javax.swing.JTextField status;
    private javax.swing.JTextField synthStatus;
    private javax.swing.JTextField synthText;
    // End of variables declaration//GEN-END:variables

    protected class MicrophoneState implements Runnable {

        @Override
        public void run() {
            while (true) {
                try {
                    state.setText(microphone.getState().toString());
                    Thread.sleep(3000);
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
    }

    protected class PlayState implements Runnable {

        @Override
        public void run() {
            while (aePlayWave.isAlive()) {
                try {
                    Thread.sleep(200);
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
            setStatus("Waiting...");
        }
    }

    protected class RecognizeThread implements Runnable {

        @Override
        public void run() {
            Recognizer recognizer = new Recognizer();
            try {
                
                setStatus("Recognizing...");
                recognizer.setLanguage(languageCode.getText());
                //recognizer.setLanguage(plugin.LANGUAGE_CODE);
                //GoogleResponse googleResponse = recognizer.getRecognizedDataForWave(file.getText());
                GoogleResponse googleResponse = recognizer.getRecognizedDataForWave(temp);
                response.setText(googleResponse.getResponse());
                plugin.setDescription("You said: " + googleResponse.getResponse());
                confidence.setText(googleResponse.getConfidence());
            } catch (Exception ex) {
                ex.printStackTrace();
            }
            setStatus("Waiting...");
            startRecognition.setEnabled(true);
        }
    }

    protected class PlayMP3Thread implements Runnable {

        @Override
        public void run() {

            Synthesiser synthesiser = new Synthesiser();

            try {
                Player player = new Player(synthesiser.getMP3Data(synthText.getText()));
                player.play();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
            setSynthStatus("Waiting...");
        }
    }
}
